package tcp_middleware

import (
	"context"
	"gin-gateway/example/gateway_demo/otherProxy/tcp_proxy"
	"math"
	"net"
)

const abortIndex int8 = math.MaxInt8 / 2 //最多 63 个中间件

// 知其然也知其所以然
type TcpHandlerFunc func(*TcpSliceRouterContext)

// TcpSliceRouter 和 TcpSliceGroup 相互可以拿对方数据
// router 结构体
type TcpSliceRouter struct {
	groups []*TcpSliceGroup // 路由组
}

// group 结构体
type TcpSliceGroup struct {
	*TcpSliceRouter // 拿到TcpSliceRouter 的地址
	path            string
	handlers        []TcpHandlerFunc // 数组 外部传入的middleware/handler逻辑
}

// router上下文
type TcpSliceRouterContext struct {
	conn net.Conn
	Ctx  context.Context
	*TcpSliceGroup
	index int8
}

func newTcpSliceRouterContext(conn net.Conn, r *TcpSliceRouter, ctx context.Context) *TcpSliceRouterContext {
	newTcpSliceGroup := &TcpSliceGroup{}
	*newTcpSliceGroup = *r.groups[0] //浅拷贝数组指针,只会使用第一个分组
	c := &TcpSliceRouterContext{conn: conn, TcpSliceGroup: newTcpSliceGroup, Ctx: ctx}
	c.Reset()
	return c
}

func (t *TcpSliceRouterContext) Get(key interface{}) interface{} {
	return t.Ctx.Value(key)
}

func (t *TcpSliceRouterContext) Set(key, val interface{}) {
	t.Ctx = context.WithValue(t.Ctx, key, val)
}

type TcpSliceRouterHandler struct {
	coreFunc func(*TcpSliceRouterContext) tcp_proxy.TCPHandler
	router   *TcpSliceRouter
}

func (t *TcpSliceRouterHandler) ServeTCP(ctx context.Context, conn net.Conn) {
	c := newTcpSliceRouterContext(conn, t.router, ctx)
	c.handlers = append(c.handlers, func(c *TcpSliceRouterContext) { // 把core里面的ServeTCP逻辑传入TcpSliceGroup handlers
		t.coreFunc(c).ServeTCP(ctx, conn)
	})
	c.Reset() // 从第index =0 开始使用
	c.Next()
	// TcpSliceRouterContext.index++
	//	for TcpSliceRouterContext.index < int8(len(TcpSliceRouterContext.handlers)) {
	//		TcpSliceRouterContext.handlers[TcpSliceRouterContext.index](TcpSliceRouterContext) // 执行中间件 从index = 0开始
	//		TcpSliceRouterContext.index++
	//	}
}

func NewTcpSliceRouterHandler(coreFunc func(*TcpSliceRouterContext) tcp_proxy.TCPHandler, router *TcpSliceRouter) *TcpSliceRouterHandler {
	return &TcpSliceRouterHandler{
		coreFunc: coreFunc,
		router:   router,
	}
}

// 构造 router
func NewTcpSliceRouter() *TcpSliceRouter {
	return &TcpSliceRouter{}
}

// 创建 Group。只接收 "/"
func (t *TcpSliceRouter) Group(path string) *TcpSliceGroup {
	if path != "/" {
		panic("only accept path=/")
	}
	return &TcpSliceGroup{
		TcpSliceRouter: t,
		path:           path,
	}
}

// 构造回调方法
func (t *TcpSliceGroup) Use(middlewares ...TcpHandlerFunc) *TcpSliceGroup {
	t.handlers = append(t.handlers, middlewares...)
	existsFlag := false
	for _, oldGroup := range t.TcpSliceRouter.groups {
		if oldGroup == t {
			existsFlag = true
		}
	}
	if !existsFlag {
		t.TcpSliceRouter.groups = append(t.TcpSliceRouter.groups, t)
	}
	return t
}

// 从最先加入中间件开始回调
func (t *TcpSliceRouterContext) Next() {
	t.index++
	for t.index < int8(len(t.handlers)) {
		t.handlers[t.index](t)
		t.index++
	}
}

// 跳出中间件方法
func (t *TcpSliceRouterContext) Abort() {
	t.index = abortIndex
}

// 是否跳过了回调
func (t *TcpSliceRouterContext) IsAborted() bool {
	return t.index >= abortIndex
}

// 重置回调 从第index =-1 开始使用
func (t *TcpSliceRouterContext) Reset() {
	t.index = -1
}
